﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text.RegularExpressions;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using 纸片人.CalculateControls;

using 纸片人.UtilFolter;
using 纸片人.win2dEffectControl;
using 纸片人.win2dEffectControl.DataClass;

// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235


namespace 纸片人.CalculateControls
{
    public class TextBoxSlider : RangeControl
    {




        #region 属性


        protected override void OnMaximumChanged(double oldValue, double newValue)
        {
            this.ValueIsChanged();
        }

        protected override void OnMinimumChanged(double oldValue, double newValue)
        {
            this.ValueIsChanged();
        }


        protected override void OnStepFrequencyChanged(double oldValue, double newValue)
        {
            this.ValueIsChanged();
        }

  
        /// <summary>
        /// 值
        /// </summary>
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(TextBoxSlider), new PropertyMetadata(0d, OnValueChanged));
        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBoxSlider tbs)
            {
                if (e.NewValue != e.OldValue)
                {
                    tbs.ValueIsChanged();
                    tbs.OnOverrideValueChanged((double)e.NewValue,(double)e.NewValue);
                    tbs.OnValueChanging(tbs, e.NewValue);
                }
            }
        }
        protected virtual void OnOverrideValueChanged(double newValue, double oldValue)
        {
          
        }


        /// <summary>
        /// 获取或设置Genre的值
        /// </summary>  
        public object Genre
        {
            get { return (object)GetValue(GenreProperty); }
            set { SetValue(GenreProperty, value); }
        }

        /// <summary>
        /// 标识 Genre 依赖属性。
        /// </summary>
        public static readonly DependencyProperty GenreProperty =
            DependencyProperty.Register("Genre", typeof(object), typeof(TextBoxSlider), new PropertyMetadata("Value：", OnGenreChanged));

        private static void OnGenreChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            TextBoxSlider target = obj as TextBoxSlider;
            object oldValue = (object)args.OldValue;
            object newValue = (object)args.NewValue;
            if (oldValue != newValue)
                target.OnGenreChanged(oldValue, newValue);
        }

        protected virtual void OnGenreChanged(object oldValue, object newValue)
        {
        }

        void ValueIsChanged()
        {
            var temp = Value;
            temp = Math.Min(this.Maximum, Math.Max(this.Minimum, temp));
            string str = temp.ToString(stepFrequency);
            temp = double.Parse(str);
            if (inputBox != null && inputBox.Text != str)
                inputBox.Text = str;
            if (temp != Value)
            {
                Value = temp;
            }
        }

        #endregion



        private double drapOldValue = 0;
        private double deltaX = 0;
        private double startDrapPosX = 0;

        private TextBox inputBox;
    
        private Thumb dragThumb;
        /// <summary>
        /// 构造函数
        /// </summary>
        public TextBoxSlider()
        {
            this.DefaultStyleKey = typeof(TextBoxSlider);
        }

        protected override void OnApplyTemplate()
        {
            //base.OnApplyTemplate();
            GetProviderAndExproterControl();
            SetInputTextBox();
            SetThumb();
            SetProviderType("Int(1)");
            SetExporterType("Out(1)");
        }

        #region 输出数据控件
        protected override void OnexporterDrag(UIElement sender, DragStartingEventArgs args)
        {
            OnDragExportInvoke();
            OutputData od = new OutputData();
            od.Type = OutputType.Double;
            od.Exporter = this;
            od.ExportConnectElement =(ExporterDragControl) sender;
            od.ExporterInfo = nameof(Value);
            EffectOutputControl.outputData = od;
        }
        #endregion

        #region  接收数据控件

  

        protected override void OnProviderEnter(object sednder, DragEventArgs e)
        {
            if (EffectOutputControl.outputData != null && EffectOutputControl.outputData.Type == OutputType.Double)
            {
                e.AcceptedOperation = DataPackageOperation.Copy;
                e.DragUIOverride.Caption = "拖进来了";
            }
        }

        protected override void OnProviderDrop(object sender, DragEventArgs e)
        {
            var outputData = EffectOutputControl.outputData;
            //判断是否形成了闭环了
            if (IsChartLoop(outputData.Exporter))
                return;
            if (outputData != null && outputData.Type == OutputType.Double)
            {
                var exporter = EffectOutputControl.outputData.Exporter;
                if (outputData.ExporterInfo is string str)
                {
                    exproterValueName = str;
                }
                else
                {
                    return;
                }

                (providerDrop as ProviderDropControl)?.SetConnectState();
                CreateConnect(ref oneConnectElement, providerDrop);
            }
        }

        #endregion

        #region 拖动控件事件

        void SetThumb()
        {
            dragThumb = GetTemplateChildFormName<Thumb>(nameof(dragThumb));
            if (dragThumb != null)
            {
                dragThumb.ManipulationMode = ManipulationModes.TranslateX;

                dragThumb.ManipulationStarted += Thumb_ManipulationStarted;
                dragThumb.ManipulationCompleted += Thumb_ManipulationCompleted;
                dragThumb.ManipulationDelta += Thumb_ManipulationDelta;
                dragThumb.PointerEntered += Thumb_PointerEntered;
                dragThumb.PointerExited += Thumb_PointerExited;
            }
        }

        /// <summary>
        /// 鼠标进入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 1);
        }

        /// <summary>
        /// 鼠标离开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 1);

        }


        /// <summary>
        ///   //拖动中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            var currentX = e.Position.X;
            Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 1);
            deltaX = currentX - startDrapPosX;
            Value = drapOldValue + deltaX * StepFrequency;
        }

        /// <summary>
        /// 拖动结束
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 1);
            OnValueChanged(this, Value);
        }

        /// <summary>
        /// 拖动开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            startDrapPosX = e.Position.X;
            drapOldValue = Value;
            deltaX = 0;
        }
        #endregion


        #region 设置输入文本框
        void SetInputTextBox()
        {
            inputBox = GetTemplateChildFormName<TextBox>(nameof(inputBox));
            if (inputBox != null)
            {
                //this.inputBox.Text = "0";
                inputBox.Text = Value.ToString();
                inputBox.TextChanged += TextBox_TextChanged;
                inputBox.LostFocus += InputBox_LostFocus;
                inputBox.KeyUp += InputBox_KeyUp;

               

            }

        }

        private void InputBox_KeyUp(object sender, KeyRoutedEventArgs e)
        {
            //判断是否是回车键或空格键
            if (e.Key == Windows.System.VirtualKey.Enter || e.Key == Windows.System.VirtualKey.Space)
            {
                InputTextConvertValue();
            }
        }

        /// <summary>
        /// 输入文本框失去焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void InputBox_LostFocus(object sender, RoutedEventArgs e)
        {
            InputTextConvertValue();
        }


        /// <summary>
        /// 文本框文本更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textbox = (TextBox)sender;
            if (!Regex.IsMatch(textbox.Text, @"^-*\d+\.?\d*$") && textbox.Text != "")
            {
                int pos = textbox.SelectionStart - 1;
                pos = Math.Max(0, pos);
                textbox.Text = textbox.Text.Remove(pos, 1);
                textbox.SelectionStart = pos;
            }
        }

        /// <summary>
        /// 输入的文本转换成值
        /// </summary>
        void InputTextConvertValue()
        {
            if (inputBox != null)
            {
                if (string.IsNullOrEmpty(inputBox.Text))
                {
                    inputBox.Text = "0";
                }
                Value = double.Parse(inputBox.Text);
            }
        }
        #endregion

        /// <summary>
        /// 计时器事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void Timer_Tick(object sender, object e)
        {
            if (oneConnectElement != null)
            {

                var exporter= oneConnectElement.Exporter;

                try
                {
                    var value = GetProvideValue(exporter, exproterValueName);
                    var f = double.Parse(value.ToString());
                    if (f != Value)
                    {
                        var oldValue = Value;
                        Value = f;
                    }
                }
                catch
                {
                    exporter.Disconnect(oneConnectElement);
                    exporter = null;
                }

            }
        }




       

    }
}
